/**
*		@file Modifies.h
*		@brief Modifies class
*
*		@author Zhou Nan
*
*		@date 1/25/2012
*/

#ifndef MODIFIES_H
#define MODIFIES_H

#include "TNode.h"
#include "GNode.h"
#include "Utility.h"
#include "VarTable.h"
#include "StmtTable.h"
#include "ProcTable.h"
#include <vector>
#include <set>
#include <queue>
#include <string>
#include <sstream>
using namespace std;

/**
*		Structure to Modifies relation for assignment
*/
struct ModifiesEntry{
	StmtNum			stmt_num;
	VarIdx			var_idx;
};

class Modifies{
public:

	/**
	*		This method will set Modifies(stmt_num_assign, var_idx)
	*		@param stmt_num_assign An assignment's StmtNum
	*/
	static void		SetModifiesA(StmtNum stmt_num_assign, VarIdx var_idx);

	/**
	*		This method will transform a vector structure to a matrix structure
	*/
	static void		RebuildModifies();

	static void		TransposeModifies();

	static void		CompleteModifes();
	/**
	*		This method will set var_set for stmt_num
	*/
	static void		SetModifiesS(StmtNum stmt_num, VarSet var_set);

	/**
	*		This method will set var_set for proc_idx
	*/
	static void		SetModifiesP(ProcIdx proc_idx, VarSet var_set);

	/**
	*		This method will return VarSet that are modified by stmt_num
	*/
	static VarSet&	GetModifiesS(StmtNum stmt_num);

	/**
	*		This method will return VarSet that are modified by stmt_num
	*/
	static VarSet&	GetModifiesP(ProcIdx proc_idx);

	/**
	*		This method will return StmtSet that modifies var_idx
	*/
	static StmtSet&	GetModifiesByS(VarIdx var_idx);

	/**
	*		This method will return ProSet that modifies var_idx
	*/
	static ProcSet&	GetModifiesByP(VarIdx var_idx);

	/**
	*		This method will check if Modifies(stmt_num, var_idx)
	*/
	static bool		IsModifiesS(StmtNum stmt_num, VarIdx var_idx);

	/**
	*		This method will check if Modifies(proc_idx, var_idx)
	*/
	static bool		IsModifiesP(ProcIdx proc_idx, VarIdx var_idx);

	/**
	*		This method will return a string representation of Modifies relation
	*/
	static string	ToString();

private:
	static vector<ModifiesEntry*>	vp_modifies_entries_;
	static vector<VarSet>			modifies_stmt_table_;
	static vector<StmtSet>			modifies_stmt_table_t_;
	static vector<VarSet>			modifies_proc_table_;
	static vector<ProcSet>			modifies_proc_table_t_;

	static StmtSet					modifies_has_s0_;	//modifies(s,_)
	static ProcSet					modifies_has_p0_;	//modifies(p,_)
	static VarSet					modifies_has_0v_;	//modifies(_,v)
	static bool						modifies_has_00_;	//modifies(_,_)
};

#endif